#include "sys.h"
#include "usart.h"
#if SYSTEM_SUPPORT_OS
#include "includes.h"
#endif
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
    int handle;
};
FILE __stdout;
_sys_exit(int x) { x = x; }

int fputc(int ch, FILE *f)
{
    while ((USART1->SR & 0X40) == 0)
        ;
    USART1->DR = (u8)ch;
    return ch;
}
#endif

#if EN_USART1_RX

u8 USART_RX_BUF[USART_REC_LEN];

u16 USART_RX_STA = 0;

void uart_init(u32 bound)
{

    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    USART_DeInit(USART1);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_InitStructure.USART_BaudRate            = bound;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE);
}
void Usart2_Init(unsigned int baud)
{
    GPIO_InitTypeDef  gpioInitStruct;
    USART_InitTypeDef usartInitStruct;
    NVIC_InitTypeDef  nvicInitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    gpioInitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
    gpioInitStruct.GPIO_Pin   = GPIO_Pin_2;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpioInitStruct);

    gpioInitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    gpioInitStruct.GPIO_Pin   = GPIO_Pin_3;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpioInitStruct);
    usartInitStruct.USART_BaudRate            = baud;
    usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    usartInitStruct.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    usartInitStruct.USART_Parity              = USART_Parity_No;
    usartInitStruct.USART_StopBits            = USART_StopBits_1;
    usartInitStruct.USART_WordLength          = USART_WordLength_8b;
    USART_Init(USART2, &usartInitStruct);
    USART_Cmd(USART2, ENABLE);
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    nvicInitStruct.NVIC_IRQChannel                   = USART2_IRQn;
    nvicInitStruct.NVIC_IRQChannelCmd                = ENABLE;
    nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    nvicInitStruct.NVIC_IRQChannelSubPriority        = 0;
    NVIC_Init(&nvicInitStruct);
}
void USART1_IRQHandler(void)
{
    u8 Res;
#ifdef SYSTEM_SUPPORT_OS
    OSIntEnter();
#endif
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        Res = USART_ReceiveData(USART1);
        if ((USART_RX_STA & 0x8000) == 0) {
            if (USART_RX_STA & 0x4000) {
                if (Res != 0x0a)
                    USART_RX_STA = 0;
                else {
                    USART_RX_STA |= 0x8000;
                    USART_RX_BUF[USART_RX_STA & 0x3fff] = '\0';
                }
            } else {
                if (Res == 0x0d)
                    USART_RX_STA |= 0x4000;
                else {
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
                    USART_RX_STA++;
                    if (USART_RX_STA > (USART_REC_LEN - 1))
                        USART_RX_STA = 0;
                }
            }
        }
    }
#ifdef SYSTEM_SUPPORT_OS
    OSIntExit();
#endif
}
#endif
void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len)
{
    unsigned short count = 0;
    for (; count < len; count++) {
        USART_SendData(USARTx, *str++);
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
            ;
    }
}
void UsartPrintf(USART_TypeDef *USARTx, char *fmt, ...)
{
    unsigned char  UsartPrintfBuf[296];
    va_list        ap;
    unsigned char *pStr = UsartPrintfBuf;
    va_start(ap, fmt);
    vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);
    va_end(ap);
    while (*pStr != 0) {
        USART_SendData(USARTx, *pStr++);
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)
            ;
    }
}
